#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <string.h>
#include <unistd.h>
#include <stdint.h>  
#include <iostream>
#include <vector>
#include <errno.h>
#include <arpa/inet.h>
#include "log.h"
#include "vector_uds_client.h"
#include "protocol.h"

VecUDSClient::VecUDSClient(){
    client_socket_ = -1;
}

bool VecUDSClient::Connect(const char *path){
    client_socket_ = socket(AF_UNIX, SOCK_STREAM, 0);
    if (client_socket_ == -1){
        log_error("创建socket失败");
        return false;
    }
    struct sockaddr_un addr;
    addr.sun_family = AF_UNIX;
    strncpy(addr.sun_path, path, sizeof(addr.sun_path));

    if (connect(client_socket_, (struct sockaddr *)&addr, sizeof(addr)) == -1){
        log_error("连接服务端失败");
        return false;
    }
    return true;
}

void VecUDSClient::Close(){
  if(client_socket_>0){
    close(client_socket_);
  }
}

int VecUDSClient::SendMessage(const char *data, int data_len){
    int send_num = 0;
    int n_write = 0;
    int ret = 0;
    do {
        ret = send(client_socket_, data + n_write, data_len - n_write, 0);
        if ( ret > 0 ){
            n_write += ret;
        } 
        else if ( ret < 0 ){
            if ( send_num < 1000 && (errno == EINTR || errno == EAGAIN) ){
                send_num++;
                continue;
            }
            else{
                // connection has issue, need to close the socket
                log_error("write socket failed, fd:%d, errno:%d", client_socket_, errno);
                return -1;
            }
        }
        else{
            if ( data_len == 0 ){ 
                return 0;
            }
            log_error("unexpected error!!!!!!!, fd:%d, errno:%d", client_socket_, errno);
            return -1;
        }
    } while ( n_write < data_len );

    return 0;
}

int VecUDSClient::ReceiveMessage(char *data, int data_len){
    int read_num = 0;
    int n_read = 0;
    int ret = 0;
    do {
        ret = recv(client_socket_, data + n_read, data_len - n_read, 0);
        if ( ret > 0 ){
            n_read += ret;
        }
        else if ( ret == 0 ){
            // close the connection
            log_error("peer close the socket, fd:%d", client_socket_);
            return -1;
        }
        else{
            if ( read_num < 1000 && (errno == EAGAIN || errno == EINTR) ){
                read_num++;
                continue;
            }
            else{
                // close the connection
                log_error("read socket failed, fd:%d, errno:%d", client_socket_, errno);
                return -1;
            }
        }
    } while ( n_read < data_len );
    return 0;
}

char* VecUDSClient::SendAndRecv(char* send_buffer , int send_length , int& recv_len)
{
    if(SendMessage(send_buffer, send_length) == -1){
        log_error("sendMessage error!!!!!!!, fd:%d, errno:%d", client_socket_, errno);
        return NULL;
    }
    log_debug("send byte len is over");

    //先接收响应头
    char header_buff[sizeof(CPacketHeader)+1] = {0};
    if(ReceiveMessage(header_buff, sizeof(CPacketHeader)) == -1){
        log_error("receiveMessage error!!!!!!!, fd:%d, errno:%d", client_socket_, errno);
        return NULL;
    }
    CPacketHeader *header = (CPacketHeader *)header_buff;
    recv_len = htonl(header->len);

    //获取需要接收的字符长度
    log_debug("data_len is %d",recv_len);
    //根据字符长度获取字符
    char *recv_buffer = (char*)malloc(recv_len);
    if(ReceiveMessage(recv_buffer, recv_len) == -1){
        log_error("receiveMessage error!!!!!!!, fd:%d, errno:%d", client_socket_, errno);
        return NULL;
    }

    log_debug("send and recv success");
    return recv_buffer;
}
